from rest_framework.decorators import action
from rest_framework.pagination import PageNumberPagination
from django.db.utils import IntegrityError
from rest_framework import viewsets
from django.http import JsonResponse, HttpResponse
from rest_framework.decorators import api_view, permission_classes

from utils.response import APIResponse
from .crawler import fetch_news
from .models import Worker, Notice, NoticeReadStatus, Comment, DingTalkRobot
from .serializers import NoticeSerializer, CommentSerializer
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.core.cache import cache
import pandas as pd
import io
import redis
import logging
import hmac
import hashlib
import base64
import time
import json
import requests
from urllib.parse import quote_plus
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
import urllib.parse

# 配置日志
logger = logging.getLogger(__name__)

# 缓存前缀
WORKER_CACHE_PREFIX = "v1:workers"
NOTICE_CACHE_PREFIX = "v1:notices"

# 简单的新闻视图
@api_view(['GET'])
def news_view(request):
    news = fetch_news()
    return APIResponse.rest_success(data=news)

# Worker 列表视图
class WorkerListView(APIView):
    permission_classes = [IsAuthenticated]

    def _get_cache_key(self, user, wno=None, page=None):
        """生成Worker缓存键"""
        return f"{WORKER_CACHE_PREFIX}:{user.id}:{wno if wno else 'all'}:page_{page}"

    def _clear_cache(self, user):
        """清除用户相关的所有Worker缓存"""
        # 清除所有分页缓存
        for page in range(1, 100):  # 假设最多100页
            cache.delete(f"{WORKER_CACHE_PREFIX}:{user.id}:all:page_{page}")
            cache.delete(f"{WORKER_CACHE_PREFIX}:{user.id}:*:page_{page}")

    def get(self, request):
        try:
            current_user = request.user
            wno = request.GET.get('wno')
            page = int(request.GET.get('page', 1))
            page_size = int(request.GET.get('page_size', 10))
            
            cache_key = self._get_cache_key(current_user, wno, page)

            # 尝试从缓存获取
            cached_data = cache.get(cache_key)
            if cached_data is not None:
                return APIResponse.rest_success(data=cached_data)

            # 数据库查询
            if wno:
                queryset = Worker.objects.filter(user=current_user, wno=wno)
            else:
                queryset = Worker.objects.filter(user=current_user)

            # 计算总数
            total = queryset.count()
            
            # 分页
            start = (page - 1) * page_size
            end = start + page_size
            workers = queryset.values()[start:end]

            workers_list = list(workers)
            result = {
                'total': total,
                'page': page,
                'page_size': page_size,
                'list': workers_list
            }
            
            cache.set(cache_key, result, timeout=300)
            return APIResponse.rest_success(data=result)

        except redis.ConnectionError as e:
            logger.error(f"Redis连接失败: {str(e)}")
            return APIResponse.rest_error(message='缓存服务不可用', status=503)
        except Exception as e:
            logger.error(f"未知错误: {str(e)}")
            return APIResponse.rest_error(message='服务器错误', status=500)

    def post(self, request):
        try:
            data = request.data.copy()
            data['user'] = request.user

            if Worker.objects.filter(user=request.user, wno=data['wno']).exists():
                return APIResponse.rest_error(message=f"工号 {data['wno']} 已存在", status=400)

            worker = Worker.objects.create(**data)
            self._clear_cache(request.user)
            return APIResponse.rest_success(data=worker.id, message='添加成功', status=201)

        except IntegrityError as e:
            return APIResponse.rest_error(message=f'数据库错误: {str(e)}', status=500)
        except Exception as e:
            logger.error(f"创建Worker错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

# Worker 详情视图
class WorkerDetailView(APIView):
    permission_classes = [IsAuthenticated]

    def _get_cache_key(self, user, wno=None, page=None):
        return f"{WORKER_CACHE_PREFIX}:{user.id}:{wno if wno else 'all'}:page_{page}"

    def _clear_cache(self, user):
        """清除用户相关的所有Worker缓存"""
        # 清除所有分页缓存
        for page in range(1, 100):  # 假设最多100页
            cache.delete(f"{WORKER_CACHE_PREFIX}:{user.id}:all:page_{page}")
            cache.delete(f"{WORKER_CACHE_PREFIX}:{user.id}:*:page_{page}")

    def put(self, request, pk):
        try:
            worker = get_object_or_404(Worker, id=pk, user=request.user)
            data = request.data
            for key, value in data.items():
                setattr(worker, key, value)
            worker.save()
            self._clear_cache(request.user)
            return APIResponse.rest_success(message='更新成功')

        except Worker.DoesNotExist:
            return APIResponse.rest_error(message='Worker不存在', status=404)
        except Exception as e:
            logger.error(f"更新Worker错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def delete(self, request, pk):
        try:
            worker = get_object_or_404(Worker, id=pk, user=request.user)
            worker.delete()
            self._clear_cache(request.user)
            return APIResponse.rest_success(message='删除成功')

        except Worker.DoesNotExist:
            return APIResponse.rest_error(message='Worker不存在', status=404)
        except Exception as e:
            logger.error(f"删除Worker错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

# Excel 导出
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def export_excel(request):
    try:
        # 直接从数据库获取数据，不使用缓存
        workers = Worker.objects.filter(user=request.user).values(
            'wno', 'name', 'position', 'gender', 'birth', 'phone', 'address'
        )
        
        if not workers:
            return APIResponse.rest_error(message='没有数据可导出', status=404)
            
        # 转换为DataFrame
        df = pd.DataFrame(list(workers))
        
        # 重命名列名为中文
        column_names = {
            'wno': '工号',
            'name': '姓名',
            'position': '职位',
            'gender': '性别',
            'birth': '出生日期',
            'phone': '手机号',
            'address': '地址'
        }
        df = df.rename(columns=column_names)

        try:
            # 创建Excel文件
            output = io.BytesIO()
        except Exception as e:
            logger.error(f"创建Excel文件错误: {str(e)}")
            return APIResponse.rest_error(message='创建Excel文件失败', status=500)
        with pd.ExcelWriter(output, engine='openpyxl') as writer:
            df.to_excel(writer, index=False, sheet_name='人员信息')
            
        # 设置响应头
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename="人员信息表.xlsx"'
        
        # 写入响应内容
        output.seek(0)
        response.write(output.getvalue())
        
        return response

    except Exception as e:
        logger.error(f"导出Excel错误: {str(e)}", exc_info=True)
        return APIResponse.rest_error(message=f'导出失败: {str(e)}', status=500)

# Excel 导入
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def import_excel(request):
    try:
        if 'file' not in request.FILES:
            return APIResponse.rest_error(message='请选择要导入的Excel文件', status=400)
            
        excel_file = request.FILES['file']
        if not excel_file.name.endswith(('.xlsx', '.xls')):
            return APIResponse.rest_error(message='请上传Excel文件(.xlsx或.xls)', status=400)
            
        # 读取Excel文件
        df = pd.read_excel(excel_file)
        
        # 检查必要的列是否存在
        required_columns = ['工号', '姓名', '职位']
        missing_columns = [col for col in required_columns if col not in df.columns]
        if missing_columns:
            return APIResponse.rest_error(
                message=f'Excel文件缺少必要的列: {", ".join(missing_columns)}', 
                status=400
            )
            
        # 重命名列名为英文
        column_names = {
            '工号': 'wno',
            '姓名': 'name',
            '职位': 'position',
            '性别': 'gender',
            '出生日期': 'birth',
            '手机号': 'phone',
            '地址': 'address'
        }
        df = df.rename(columns=column_names)
        
        # 处理日期列，将NaT转换为默认日期
        if 'birth' in df.columns:
            df['birth'] = df['birth'].fillna('2000-01-01')
        
        # 获取现有工号列表
        existing_workers = {
            worker.wno: worker 
            for worker in Worker.objects.filter(user=request.user)
        }
        
        # 准备批量创建和更新的数据
        to_create = []
        to_update = []
        updated_count = 0
        created_count = 0
        
        for _, row in df.iterrows():
            # 处理日期值
            birth_date = row.get('birth')
            if pd.isna(birth_date) or birth_date == 'NaT':
                birth_date = '2000-01-01'
                
            worker_data = {
                'user': request.user,
                'wno': str(row['wno']),  # 确保工号为字符串
                'name': str(row['name']),
                'position': str(row['position']),
                'gender': str(row.get('gender', '')),
                'birth': birth_date,
                'phone': str(row.get('phone', '')),
                'address': str(row.get('address', ''))
            }
            
            if worker_data['wno'] in existing_workers:
                # 更新现有记录
                worker = existing_workers[worker_data['wno']]
                for key, value in worker_data.items():
                    if key != 'user':  # 不更新user字段
                        setattr(worker, key, value)
                to_update.append(worker)
                updated_count += 1
            else:
                # 创建新记录
                to_create.append(Worker(**worker_data))
                created_count += 1
        
        # 批量创建新记录
        if to_create:
            Worker.objects.bulk_create(to_create)
            
        # 批量更新现有记录
        if to_update:
            Worker.objects.bulk_update(
                to_update,
                ['name', 'position', 'gender', 'birth', 'phone', 'address']
            )
        
        # 清除缓存
        WorkerListView()._clear_cache(request.user)
        
        return APIResponse.rest_success(
            message=f'成功导入 {created_count} 条新数据，更新 {updated_count} 条现有数据',
            data={
                'created_count': created_count,
                'updated_count': updated_count
            }
        )

    except pd.errors.EmptyDataError:
        return APIResponse.rest_error(message='Excel文件为空', status=400)
    except Exception as e:
        logger.error(f"导入Excel错误: {str(e)}", exc_info=True)
        return APIResponse.rest_error(message=f'导入失败: {str(e)}', status=500)

# 分页配置
class NoticePagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100

# 通知视图集
class NoticeViewSet(viewsets.ViewSet):
    permission_classes = [IsAuthenticated]
    queryset = Notice.objects.filter(is_active=True)
    pagination_class = NoticePagination

    def _get_cache_key(self, user, notice_type=None):
        """生成Notice缓存键"""
        key = f"{NOTICE_CACHE_PREFIX}:{user.id}"
        if notice_type:
            key = f"{key}:{notice_type}"
        return key

    def _clear_cache(self, user, notice_type=None):
        """清除用户相关的通知缓存"""
        cache.delete(self._get_cache_key(user))
        if notice_type:
            cache.delete(self._get_cache_key(user, notice_type))

    def _check_system_notice_permission(self, request):
        """检查是否有权限发送系统通知"""
        if not request.user.is_staff:
            return APIResponse.rest_error(message='只有管理员可以发送系统通知', status=403)
        return None

    def list(self, request):
        try:
            notice_type = request.GET.get('type')
            cache_key = self._get_cache_key(request.user, notice_type)
            cached_data = cache.get(cache_key)

            if cached_data is not None:
                paginator = self.pagination_class()
                page = paginator.paginate_queryset(cached_data, request)
                return APIResponse.rest_success(
                    data=page,
                    message='获取成功'
                )

            # 如果没有缓存，从数据库查询
            queryset = self.queryset
            if notice_type:
                queryset = queryset.filter(notice_type=notice_type)

            paginator = self.pagination_class()
            page = paginator.paginate_queryset(queryset, request)
            serializer = NoticeSerializer(page, many=True, context={'request': request})
            
            # 缓存序列化后的数据
            cache.set(cache_key, serializer.data, timeout=300)
            
            return APIResponse.rest_success(data=serializer.data)

        except redis.ConnectionError as e:
            logger.error(f"Redis连接失败: {str(e)}")
            return APIResponse.rest_error(message='缓存服务不可用', status=503)
        except Exception as e:
            logger.error(f"获取通知列表错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def retrieve(self, request, pk=None):
        try:
            notice = get_object_or_404(self.queryset, pk=pk)
            serializer = NoticeSerializer(notice, context={'request': request})
            
            # 标记为已读
            status, _ = NoticeReadStatus.objects.get_or_create(user=request.user, notice=notice)
            if not status.is_read:
                status.is_read = True
                status.read_at = timezone.now()
                status.save()
                self._clear_cache(request.user)

            # 获取评论
            comments = notice.comments.all()
            paginator = self.pagination_class()
            comment_page = paginator.paginate_queryset(comments, request)
            comment_serializer = CommentSerializer(comment_page, many=True, context={'request': request})
            
            data = serializer.data
            data['comments'] = comment_serializer.data
            return APIResponse.rest_success(data=data)

        except Exception as e:
            logger.error(f"获取通知详情错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def create(self, request):
        try:
            # 检查是否是系统通知
            if request.data.get('notice_type') == 'system':
                permission_check = self._check_system_notice_permission(request)
                if permission_check:
                    return permission_check

            serializer = NoticeSerializer(data=request.data, context={'request': request})
            if serializer.is_valid():
                notice = serializer.save(publisher=request.user)
                self._clear_cache(request.user, notice.notice_type)
                return APIResponse.rest_success(data=serializer.data, message='发布成功')
            return APIResponse.rest_error(message='数据验证失败', data=serializer.errors, status=400)

        except Exception as e:
            logger.error(f"创建通知错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def update(self, request, pk=None):
        try:
            notice = get_object_or_404(self.queryset, pk=pk)
            
            # 检查是否是系统通知
            if request.data.get('notice_type') == 'system' or notice.notice_type == 'system':
                permission_check = self._check_system_notice_permission(request)
                if permission_check:
                    return permission_check

            if notice.publisher != request.user:
                return APIResponse.rest_error(message='只能修改自己的通知', status=403)
            
            serializer = NoticeSerializer(notice, data=request.data, partial=True, context={'request': request})
            if serializer.is_valid():
                notice = serializer.save()
                self._clear_cache(request.user, notice.notice_type)
                return APIResponse.rest_success(data=serializer.data, message='更新成功')
            return APIResponse.rest_error(message='数据验证失败', data=serializer.errors, status=400)

        except Exception as e:
            logger.error(f"更新通知错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def destroy(self, request, pk=None):
        try:
            notice = get_object_or_404(self.queryset, pk=pk)
            
            # 检查是否是系统通知
            if notice.notice_type == 'system':
                permission_check = self._check_system_notice_permission(request)
                if permission_check:
                    return permission_check

            if notice.publisher != request.user:
                return APIResponse.rest_error(message='只能删除自己的通知', status=403)
            
            notice_type = notice.notice_type
            notice.is_active = False
            notice.save()
            self._clear_cache(request.user, notice_type)
            return APIResponse.rest_success(message='删除成功')

        except Exception as e:
            logger.error(f"删除通知错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    @action(detail=True, methods=['post'])
    def like(self, request, pk=None):
        try:
            notice = get_object_or_404(self.queryset, pk=pk)
            user = request.user
            if notice.likes.filter(id=user.id).exists():
                notice.likes.remove(user)
                msg = '取消点赞成功'
            else:
                notice.likes.add(user)
                msg = '点赞成功'
            self._clear_cache(request.user, notice.notice_type)
            serializer = NoticeSerializer(notice, context={'request': request})
            return APIResponse.rest_success(data=serializer.data, message=msg)

        except Exception as e:
            logger.error(f"点赞通知错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    @action(detail=False, methods=['post'])
    def mark_all_read(self, request):
        try:
            unread_statuses = NoticeReadStatus.objects.filter(user=request.user, is_read=False)
            if unread_statuses.exists():
                unread_statuses.update(is_read=True, read_at=timezone.now())

            unread_notices = Notice.objects.filter(is_active=True).exclude(read_statuses__user=request.user)
            if unread_notices.exists():
                new_statuses = [
                    NoticeReadStatus(
                        user=request.user,
                        notice=notice,
                        is_read=True,
                        read_at=timezone.now()
                    ) for notice in unread_notices
                ]
                NoticeReadStatus.objects.bulk_create(new_statuses)

            self._clear_cache(request.user)
            return APIResponse.rest_success(message='全部标记为已读成功')

        except Exception as e:
            logger.error(f"标记全部已读错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    @action(detail=True, methods=['put'])
    def read(self, request, pk=None):
        try:
            notice = get_object_or_404(self.queryset, pk=pk)
            status, _ = NoticeReadStatus.objects.get_or_create(user=request.user, notice=notice)
            if not status.is_read:
                status.is_read = True
                status.read_at = timezone.now()
                status.save()
                self._clear_cache(request.user)
            serializer = NoticeSerializer(notice, context={'request': request})
            return APIResponse.rest_success(data=serializer.data, message='标记为已读成功')

        except Exception as e:
            logger.error(f"标记已读错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

# 评论视图集
class CommentViewSet(viewsets.ViewSet):
    permission_classes = [IsAuthenticated]

    def list(self, request, notice_id=None):
        try:
            notice = get_object_or_404(Notice, pk=notice_id)
            comments = notice.comments.all()
            paginator = NoticePagination()
            page = paginator.paginate_queryset(comments, request)
            serializer = CommentSerializer(page, many=True, context={'request': request})
            return APIResponse.rest_success(data=serializer.data, message='获取评论成功')
        except Exception as e:
            logger.error(f"获取评论列表错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def create(self, request, notice_id=None):
        try:
            notice = get_object_or_404(Notice, pk=notice_id)
            serializer = CommentSerializer(data=request.data, context={'request': request})
            if serializer.is_valid():
                serializer.save(publisher=request.user, notice=notice)
                NoticeViewSet()._clear_cache(request.user)
                return APIResponse.rest_success(data=serializer.data, message='评论成功', status=201)
            return APIResponse.rest_error(message='评论失败', data=serializer.errors, status=400)
        except Exception as e:
            logger.error(f"创建评论错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def retrieve(self, request, notice_id=None, pk=None):
        try:
            comment = get_object_or_404(Comment, pk=pk, notice_id=notice_id)
            serializer = CommentSerializer(comment, context={'request': request})
            return APIResponse.rest_success(data=serializer.data)
        except Exception as e:
            logger.error(f"获取评论详情错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def update(self, request, notice_id=None, pk=None):
        try:
            comment = get_object_or_404(Comment, pk=pk, notice_id=notice_id)
            if comment.publisher != request.user:
                return APIResponse.rest_error(message='只能修改自己的评论', status=403)
            serializer = CommentSerializer(comment, data=request.data, partial=True, context={'request': request})
            if serializer.is_valid():
                serializer.save()
                NoticeViewSet()._clear_cache(request.user)
                return APIResponse.rest_success(data=serializer.data, message='更新成功')
            return APIResponse.rest_error(message='数据验证失败', data=serializer.errors, status=400)
        except Exception as e:
            logger.error(f"更新评论错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def destroy(self, request, notice_id=None, pk=None):
        try:
            comment = get_object_or_404(Comment, pk=pk, notice_id=notice_id)
            if comment.publisher != request.user:
                return APIResponse.rest_error(message='只能删除自己的评论', status=403)
            comment.delete()
            NoticeViewSet()._clear_cache(request.user)
            return APIResponse.rest_success(message='删除成功')
        except Exception as e:
            logger.error(f"删除评论错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    @action(detail=True, methods=['post'])
    def like(self, request, notice_id=None, pk=None):
        try:
            comment = get_object_or_404(Comment, pk=pk, notice_id=notice_id)
            user = request.user
            if comment.likes.filter(id=user.id).exists():
                comment.likes.remove(user)
                msg = '取消点赞成功'
            else:
                comment.likes.add(user)
                msg = '点赞成功'
            serializer = CommentSerializer(comment, context={'request': request})
            return APIResponse.rest_success(data=serializer.data, message=msg)
        except Exception as e:
            logger.error(f"点赞评论错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

class DingTalkRobotView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        """获取用户的钉钉机器人配置"""
        try:
            robot = DingTalkRobot.objects.filter(user=request.user).first()
            if robot:
                return APIResponse.rest_success(data={
                    'webhook': robot.webhook,
                    'secret': robot.secret,
                    'is_active': robot.is_active
                })
            return APIResponse.rest_success(data=None, message='未配置钉钉机器人')
        except Exception as e:
            logger.error(f"获取钉钉机器人配置错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def post(self, request):
        """配置钉钉机器人"""
        try:
            webhook = request.data.get('webhook')
            secret = request.data.get('secret')
            is_active = request.data.get('is_active', True)  # 默认值为True
            
            if not webhook:
                return APIResponse.rest_error(message='Webhook地址不能为空', status=400)

            # 验证webhook是否有效
            try:
                response = requests.post(webhook, json={'msgtype': 'text', 'text': {'content': '测试消息'}})
                if response.status != 200:
                    return APIResponse.rest_error(message='Webhook地址无效', status=400)
            except Exception as e:
                return APIResponse.rest_error(message='Webhook地址无效', status=400)

            robot, created = DingTalkRobot.objects.update_or_create(
                user=request.user,
                defaults={
                    'webhook': webhook,
                    'secret': secret,
                    'is_active': is_active
                }
            )

            return APIResponse.rest_success(data={
                'webhook': robot.webhook,
                'is_active': robot.is_active
            }, message='配置成功')
        except Exception as e:
            logger.error(f"配置钉钉机器人错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def put(self, request):
        """更改钉钉机器人"""
        try:
            webhook = request.data.get('webhook')
            secret = request.data.get('secret')
            is_active = request.data.get('is_active', True)  # 默认值为True

            if not webhook:
                return APIResponse.rest_error(message='Webhook地址不能为空', status=400)

            # 验证webhook是否有效
            try:
                response = requests.post(webhook, json={'msgtype': 'text', 'text': {'content': '测试消息'}})
                if response.status_code != 200:
                    return APIResponse.rest_error(message='Webhook地址无效', status=400)
            except Exception as e:
                return APIResponse.rest_error(message='Webhook地址无效', status=400)

            robot, created = DingTalkRobot.objects.update_or_create(
                user=request.user,
                defaults={
                    'webhook': webhook,
                    'secret': secret,
                    'is_active': is_active
                }
            )

            return APIResponse.rest_success(data={
                'webhook': robot.webhook,
                'is_active': robot.is_active
            }, message='修改成功')
        except Exception as e:
            logger.error(f"配置钉钉机器人错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

    def delete(self, request):
        """删除钉钉机器人配置"""
        try:
            robot = get_object_or_404(DingTalkRobot, user=request.user)
            robot.delete()
            return APIResponse.rest_success(message='删除成功')
        except Exception as e:
            logger.error(f"删除钉钉机器人配置错误: {str(e)}")
            return APIResponse.rest_error(message=str(e), status=500)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def send_dingtalk_message(request):
    """发送钉钉消息"""
    try:
        message_type = request.data.get('type')
        message_data = request.data.get('data')
        if not message_data:
            return APIResponse.rest_error(message='消息内容不能为空', status=400)

        robot = get_object_or_404(DingTalkRobot, user=request.user)
        if not robot.is_active:
            return APIResponse.rest_error(message='钉钉机器人未激活', status=400)

        # 根据消息类型格式化消息
        if message_type == 'realtime':
            formatted_message = format_realtime_message(message_data)
        elif message_type == 'video':
            formatted_message = format_video_message(message_data)
        else:
            return APIResponse.rest_error(message='不支持的消息类型', status=400)

        # 准备请求头
        headers = {
            'Content-Type': 'application/json'
        }

        # 如果有密钥，生成签名
        secret = robot.secret
        if secret:
            timestamp = str(round(time.time() * 1000))
            secret_enc = secret.encode('utf-8')
            string_to_sign = '{}\n{}'.format(timestamp, secret)
            string_to_sign_enc = string_to_sign.encode('utf-8')
            hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
            sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))

            # 将签名和时间戳添加到webhook URL
            base_url = robot.webhook.split('?')[0]
            access_token = robot.webhook.split('access_token=')[1]
            webhook_url = f"{base_url}?access_token={access_token}&timestamp={timestamp}&sign={sign}"
            
            logger.info(f"Generated webhook URL: {webhook_url}")
        else:
            webhook_url = robot.webhook
        
        # 发送消息到钉钉
        try:
            response = requests.post(
                webhook_url,
                headers=headers,
                json=formatted_message,
                timeout=5
            )
            response.raise_for_status()
            result = response.json()
            
            if result.get('errcode') == 0:
                return APIResponse.rest_success(message='消息发送成功')
            else:
                logger.error(f"钉钉返回错误: {result}")
                return APIResponse.rest_error(message=f'钉钉返回错误: {result.get("errmsg")}', status=400)
        except requests.exceptions.RequestException as e:
            logger.error(f"发送钉钉消息失败: {str(e)}")
            return APIResponse.rest_error(message=f'发送钉钉消息失败: {str(e)}', status=500)

    except Exception as e:
        logger.error(f"处理钉钉消息时发生错误: {str(e)}", exc_info=True)
        return APIResponse.rest_error(message=f'处理消息时发生错误: {str(e)}', status=500)

def format_realtime_message(data):
    """格式化实时检测消息"""
    try:
        # 从嵌套的data中获取实际数据
        if isinstance(data, dict) and 'data' in data:
            data = data['data']
            
        session_id = data.get('session_id')
        start_time = data.get('start_time')
        end_time = data.get('end_time')
        detection_details = data.get('detection_details', [])
        
        # 统计各类别检测次数
        detection_counts = {}
        for detail in detection_details:
            class_name = detail.get('class_name')
            if class_name:
                detection_counts[class_name] = detection_counts.get(class_name, 0) + 1

        # 构建消息内容
        message = f"## 实时检测完成通知\n\n"
        message += f"### 会话信息\n"
        message += f"- 会话ID: {session_id}\n"
        message += f"- 开始时间: {start_time}\n"
        message += f"- 结束时间: {end_time}\n\n"
        
        message += f"### 检测统计\n"
        for class_name, count in detection_counts.items():
            message += f"- {class_name}: {count}次\n"

        return {
            "msgtype": "markdown",
            "markdown": {
                "title": "实时检测完成通知",
                "text": message
            }
        }
    except Exception as e:
        logger.error(f"格式化实时检测消息失败: {str(e)}", exc_info=True)
        raise

def format_video_message(data):
    """格式化视频检测消息"""
    try:
        # 从嵌套的data中获取实际数据
        if isinstance(data, dict) and 'data' in data:
            data = data['data']
            
        video_name = data.get('video_name')
        uploaded_at = data.get('uploaded_at')
        detection_summary = data.get('detection_summary', {})
        detection_details = data.get('detection_details', [])
        
        # 构建消息内容
        message = f"## 视频检测完成通知\n\n"
        message += f"### 视频信息\n"
        message += f"- 视频名称: {video_name or '未命名视频'}\n"
        message += f"- 上传时间: {uploaded_at}\n\n"
        
        if detection_summary:
            message += f"### 检测统计\n"
            for class_name, count in detection_summary.items():
                message += f"- {class_name}: {count}次\n"
        else:
            message += f"### 检测结果\n"
            message += f"- 未检测到任何目标\n"

        return {
            "msgtype": "markdown",
            "markdown": {
                "title": "视频检测完成通知",
                "text": message
            }
        }
    except Exception as e:
        logger.error(f"格式化视频检测消息失败: {str(e)}", exc_info=True)
        raise